using Avalonia;
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Threading;
using Avalonia.Styling;
using SerialTool.Controls;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;

namespace SerialTool.Services;

public enum ToastType
{
    Information,
    Success,
    Warning,
    Error
}

public class ToastService
{
    private static ToastService? _instance;
    private Panel? _container;
    private readonly Queue<ToastInfo> _pendingToasts = new();
    private bool _isShowingToast = false;

    private class ToastInfo
    {
        public required string Title { get; set; }
        public required string Message { get; set; }
        public required ToastType Type { get; set; }
        public TimeSpan Duration { get; set; } = TimeSpan.FromSeconds(3);
    }

    private ToastService() { }

    public static ToastService Instance => _instance ??= new ToastService();

    public void Initialize(Panel container)
    {
        _container = container;
    }

    public void ShowToast(string title, string message, ToastType type = ToastType.Information, TimeSpan? duration = null)
    {
        if (_container == null)
        {
            Console.WriteLine("Toast container not initialized");
            return;
        }

        var toastInfo = new ToastInfo
        {
            Title = title,
            Message = message,
            Type = type,
            Duration = duration ?? TimeSpan.FromSeconds(3)
        };

        _pendingToasts.Enqueue(toastInfo);
        ProcessPendingToasts();
    }

    private void ProcessPendingToasts()
    {
        if (_isShowingToast || _pendingToasts.Count == 0) return;

        _isShowingToast = true;
        var toastInfo = _pendingToasts.Dequeue();
        ShowToastImpl(toastInfo);
    }

    private async void ShowToastImpl(ToastInfo toastInfo)
    {
        await Dispatcher.UIThread.InvokeAsync(async () =>
        {
            var toast = new ToastNotification
            {
                Title = toastInfo.Title,
                Message = toastInfo.Message,
                Width = 300,
                Margin = new Thickness(0, 0, 16, 16),
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Bottom,
                Opacity = 0,
                RenderTransform = new TranslateTransform(50, 0)
            };

            // 设置图标和颜色
            switch (toastInfo.Type)
            {
                case ToastType.Success:
                    toast.Icon = "✓";
                    toast.IconColor = Brushes.LightGreen;
                    break;
                case ToastType.Warning:
                    toast.Icon = "⚠";
                    toast.IconColor = Brushes.Orange;
                    break;
                case ToastType.Error:
                    toast.Icon = "✗";
                    toast.IconColor = Brushes.Red;
                    break;
                case ToastType.Information:
                default:
                    toast.Icon = "ℹ";
                    toast.IconColor = Brushes.SkyBlue;
                    break;
            }

            // 添加到容器
            _container!.Children.Add(toast);

            // 显示动画
            var fadeIn = new Animation
            {
                Duration = TimeSpan.FromMilliseconds(300),
                FillMode = FillMode.Forward,
                Easing = new CubicEaseOut()
            };

            fadeIn.Children.Add(new KeyFrame
            {
                Cue = new Cue(0d),
                Setters = { new Setter { Property = Visual.OpacityProperty, Value = 0d } }
            });

            fadeIn.Children.Add(new KeyFrame
            {
                Cue = new Cue(1d),
                Setters = { new Setter { Property = Visual.OpacityProperty, Value = 1d } }
            });

            var moveIn = new Animation
            {
                Duration = TimeSpan.FromMilliseconds(300),
                FillMode = FillMode.Forward,
                Easing = new CubicEaseOut()
            };

            moveIn.Children.Add(new KeyFrame
            {
                Cue = new Cue(0d),
                Setters = { new Setter { Property = TranslateTransform.XProperty, Value = 50d } }
            });

            moveIn.Children.Add(new KeyFrame
            {
                Cue = new Cue(1d),
                Setters = { new Setter { Property = TranslateTransform.XProperty, Value = 0d } }
            });

            await fadeIn.RunAsync(toast);
            await moveIn.RunAsync(toast, CancellationToken.None);

            // 等待指定时间
            await Task.Delay(toastInfo.Duration);

            // 隐藏动画
            var fadeOut = new Animation
            {
                Duration = TimeSpan.FromMilliseconds(300),
                FillMode = FillMode.Forward,
                Easing = new CubicEaseIn()
            };

            fadeOut.Children.Add(new KeyFrame
            {
                Cue = new Cue(0d),
                Setters = { new Setter { Property = Visual.OpacityProperty, Value = 1d } }
            });

            fadeOut.Children.Add(new KeyFrame
            {
                Cue = new Cue(1d),
                Setters = { new Setter { Property = Visual.OpacityProperty, Value = 0d } }
            });

            var moveOut = new Animation
            {
                Duration = TimeSpan.FromMilliseconds(300),
                FillMode = FillMode.Forward,
                Easing = new CubicEaseIn()
            };

            moveOut.Children.Add(new KeyFrame
            {
                Cue = new Cue(0d),
                Setters = { new Setter { Property = TranslateTransform.XProperty, Value = 0d } }
            });

            moveOut.Children.Add(new KeyFrame
            {
                Cue = new Cue(1d),
                Setters = { new Setter { Property = TranslateTransform.XProperty, Value = 50d } }
            });

            await fadeOut.RunAsync(toast);
            await moveOut.RunAsync(toast, CancellationToken.None);

            // 从容器中移除
            _container!.Children.Remove(toast);

            // 处理下一个Toast
            _isShowingToast = false;
            ProcessPendingToasts();
        });
    }
} 